
import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.AlertType;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.List;
import javax.microedition.lcdui.TextField;
import javax.microedition.midlet.*;
import javax.microedition.rms.RecordStore;

/**
 * @author S3157015
 */
public class ReversiMidlet extends MIDlet implements CommandListener {

    private Display display;
    private Command backCommand;
    private Command quitGameCommand;
    private Command restartCommand;
    private Command finishCommand;
    private Alert alert;
    private Alert wrongInputAlert;
    private Command select;
    private List mainMenu;
    private String[] stringElements = {"New Game", "Bluetooth Game", "Game Setting", "Records", "Exit"};
    private ReversiCanvas rc;
    private Form form;
    private Form recordForm;
    private Form gameSettingForm;
    private TextField playerOne;
    private TextField playerTwo;
    private TextField sound;
    private TextField animation;
    private Command submit;
    private int oldState;
    private RecordStore recordstore = null;
    private RecordStore gameSetting = null;
    private RecordStore uploading = null;

    public void startApp() {
        display = Display.getDisplay(this);

        if (mainMenu == null) {
            sound = new TextField("Sound: ", "", 6, TextField.ANY);
            animation = new TextField("Animation: ", "", 6, TextField.ANY);
            mainMenu = new List("Reservation type", List.IMPLICIT, stringElements, null);
            select = new Command("Select", Command.SCREEN, 1);
            backCommand = new Command("Back", Command.BACK, 2);
            submit = new Command("Submit", Command.SCREEN, 1);
            finishCommand = new Command("Done", Command.SCREEN, 1);
            mainMenu.addCommand(select);
            mainMenu.setCommandListener(this);
            display.setCurrent(mainMenu);
            oldState = 0;
        }
    }

    public void pauseApp() {
    }

    public void destroyApp(boolean unconditional) {
    }

    //main command action
    public void commandAction(Command c, Displayable d) {
        if (c == backCommand) {
            display.setCurrent(mainMenu);
            //main menu    
        } else if (d == mainMenu) {
            if (c == select) {
                int index = mainMenu.getSelectedIndex();
                switch (index) {
                    case AllDef.NEWGAME:
                        Display.getDisplay(this).setCurrent(getForm());
                        break;
                    case AllDef.BLUETOOTHGAME:
                        System.out.println("bluetooth gaming");
                        break;
                    case AllDef.GAMESETTING:
                        Display.getDisplay(this).setCurrent(getGameSettingForm());
                        System.out.println("game setting");
                        break;
                    case AllDef.RECORDS:
                        Display.getDisplay(this).setCurrent(getRecordForm());
                        System.out.println("records");
                        break;
                    case AllDef.EXIT:
                        notifyDestroyed();
                        destroyApp(true);
                        break;
                }
            }
            // this fomr is used to let user input name
        } else if (d == form) {
            if (c == submit) {
                //user name can not be empty
                if (playerOne.getString().length() == 0 || playerTwo.getString().length() == 0) {

                    alert = new Alert("Input Alert", "players name can not be empty", null, AlertType.INFO);
                    alert.setTimeout(Alert.FOREVER);
                    display.setCurrent(alert);
                    //user name can not be the same    
                } else if (playerOne.getString().equals(playerTwo.getString())) {
                    alert = new Alert("Input Alert", "players name can not be the same", null, AlertType.INFO);
                    alert.setTimeout(Alert.FOREVER);
                    display.setCurrent(alert);
                } else {
                    display.setCurrent(getReversiCanvas(playerOne.getString(), playerTwo.getString()));
                }
            }
        } else if (d == rc) {
            //restart game
            if (c == restartCommand) {
                rc.getGame().setState(AllDef.RUN);
                rc.getGame().setTurn(AllDef.BLACK);
                rc.getGame().getBlack().init();
            }
            //game setting form    
        } else if (d == gameSettingForm) {
            if (c == finishCommand) {
                if ((!sound.getString().toLowerCase().equals("on")
                        && !sound.getString().toLowerCase().equals("off"))
                        || (!animation.getString().toLowerCase().equals("on")
                        && !animation.getString().toLowerCase().equals("off"))) {
                    wrongInputAlert = new Alert("Input Alert", "input string must be on or off (case insensitive)", null, AlertType.INFO);
                    wrongInputAlert.setTimeout(Alert.FOREVER);
                    display.setCurrent(wrongInputAlert);
                } else {
                    try {
                        //store the user setting
                        gameSetting =
                                RecordStore.openRecordStore("GameSetting", true);
                        byte[] byteSound = sound.getString().getBytes();
                        byte[] byteAnimation = animation.getString().getBytes();
                        gameSetting.setRecord(1, byteSound, 0, byteSound.length);
                        gameSetting.setRecord(2, byteAnimation, 0, byteAnimation.length);
                        gameSetting.closeRecordStore();
                        display.setCurrent(mainMenu);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        if (c == quitGameCommand) {
            rc.getGame().stopMusic();
            rc.getGame().stopBackGroundMusic();
            rc.stop();
            display.setCurrent(mainMenu);
            rc = null;
            playerOne.setString(null);
            playerTwo.setString(null);

        }
    }

    //this is the main game canvas
    private ReversiCanvas getReversiCanvas(String name1, String name2) {
        if (rc == null) {
            rc = new ReversiCanvas(new Game(name1, name2));
            rc.start();
            oldState = AllDef.RUN;
            rc.getGame().setState(oldState);
            restartCommand = new Command("Restart", Command.SCREEN, 3);
            quitGameCommand = new Command("Quit", Command.SCREEN, 3);
            rc.addCommand(restartCommand);
            rc.addCommand(quitGameCommand);
            rc.setCommandListener(this);
        }
        return rc;
    }

    // user nmae inuput fomr
    private Form getForm() {
        if (form == null) {
            form = new Form("Player name");
            playerOne = new TextField("First Player Name:\n", "", 6, TextField.ANY);
            playerTwo = new TextField("Second Player Name:\n", "", 6, TextField.ANY);
            playerOne.setPreferredSize(500, 30);
            playerTwo.setPreferredSize(500, 30);
            form.addCommand(backCommand);
            form.addCommand(submit);
            form.append(playerOne);
            form.append(playerTwo);
            form.setCommandListener(this);
        }
        return form;
    }

    //game setting form
    private Form getGameSettingForm() {
        String setting = null;
        String soundString;
        String animationString;
        if (gameSettingForm == null) {
            gameSettingForm = new Form("Game Setting");
            gameSettingForm.append(sound);
            gameSettingForm.append(animation);
            gameSettingForm.addCommand(backCommand);
            gameSettingForm.addCommand(finishCommand);
            gameSettingForm.setCommandListener(this);
        }
        try {
            gameSetting =
                    RecordStore.openRecordStore("GameSetting", true);
            
            // game played in first time. set defaut setting
            if (gameSetting.getNumRecords() == 0) {
                soundString = "On";
                animationString = "On";
                sound.setString("On");
                animation.setString("On");
                byte[] byteSound = soundString.getBytes();
                byte[] byteAnimation = animationString.getBytes();
                gameSetting.addRecord(byteSound, 0, byteSound.length);
                gameSetting.addRecord(byteAnimation, 0, byteAnimation.length);
            //set the game accroding user's input    
            } else {
                byte[] soundTmp = gameSetting.getRecord(1);
                byte[] animationTmp = gameSetting.getRecord(2);
                gameSetting.closeRecordStore();
                soundString = new String(soundTmp, 0, soundTmp.length);
                animationString = new String(animationTmp, 0, animationTmp.length);
                sound.setString(soundString);
                animation.setString(animationString);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return gameSettingForm;
    }

    //record form
    private Form getRecordForm() {

        String record = null;
        recordForm = new Form("Records");
        try {
            recordstore =
                    RecordStore.openRecordStore(
                    "GameRecords", true);
//            recordstore.closeRecordStore();
//            recordstore.deleteRecordStore("GameRecords");
            if (recordstore.getNumRecords() == 0) {
                recordForm.append("No records now");
            } else {
                System.out.println(recordstore.getNumRecords());
            }
        } catch (Exception error) {
            error.printStackTrace();
        }

        try {
            for (int i = 1; i < recordstore.getNumRecords() + 1; i++) {
                byte b[] = recordstore.getRecord(i);
                record = new String(b, 0, b.length);
                recordForm.append(record + "\n");
            }
            recordstore.closeRecordStore();

        } catch (Exception e) {
            e.printStackTrace();
        }
        recordForm.addCommand(backCommand);
        recordForm.setCommandListener(this);

        return recordForm;
    }
}
